home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / quicktime / effects / qtshoweffect / application files / comapplication.c next >
Encoding:
Text File  |  2000-09-28  |  14.4 KB  |  537 lines

  1. //////////
  2. //
  3. //    File:        ComApplication.c
  4. //
  5. //    Contains:    Application-specific code for basic QuickTime movie display and control.
  6. //                This file is used for BOTH MacOS and Windows.
  7. //
  8. //    Written by:    Tim Monroe
  9. //                Based on the MovieShell code written by Apple DTS.
  10. //
  11. //    Copyright:    © 1994-1997 by Apple Computer, Inc., all rights reserved.
  12. //
  13. //    Change History (most recent first):
  14. //
  15. //       <19>         05/03/99    rtm        removed support for compound effects; to be provided at some later time
  16. //       <18>         12/16/98    rtm        removed all QTVR API calls, so we can remove QTVR.lib from project
  17. //       <17>         05/21/98    rtm        removed conditionalized support for compound effects
  18. //       <16>         02/20/98    rtm        revised custom dialog box handling; now works on Windows (yippee!)
  19. //       <15>         02/12/98    rtm        added support for stepping through the effect
  20. //       <14>         02/05/98    rtm        reworked HandleContentClick and DoApplicationEventLoopAction
  21. //       <13>         12/18/97    rtm        added low-level effects calls for QTShowEffect
  22. //       <12>         11/21/97    rtm        added code to DoApplicationEventLoopAction to handle effects dialog events
  23. //       <11>         11/06/97    rtm        removed QTVR support; added support for MakeEffectMovie routines
  24. //       <10>         10/23/97    rtm        moved InitializeQTVR to InitApplication, TerminateQTVR to StopApplication
  25. //       <9>         10/13/97    rtm        reworked HandleApplicationMenu to use menu identifiers
  26. //       <8>         09/11/97    rtm        merged MacApplication.c and WinApplication.c into ComApplication.c
  27. //       <7>         08/21/97    rtm        first file for Windows; based on MacApplication.c for Mac sample code
  28. //       <6>         06/04/97    rtm        removed call to QTVRUtils_IsQTVRMovie in InitApplicationWindowObject
  29. //       <5>         02/06/97    rtm        fixed window resizing code
  30. //       <4>         12/05/96    rtm        added hooks into MacFramework.c: StopApplication, InitApplicationWindowObject
  31. //       <3>         12/02/96    rtm        added cursor updating to DoIdle
  32. //       <2>         11/27/96    rtm        conversion to personal coding style; added preliminary QTVR support
  33. //       <1>         12/21/94    khs        first file
  34. //       
  35. //////////
  36.  
  37. // header files
  38. #include "ComApplication.h"
  39. #include "QTShowEffect.h"
  40.  
  41. // global variables for Macintosh code
  42. #if TARGET_OS_MAC
  43. extern Boolean                gQuitFlag;
  44. #endif
  45.  
  46. // global variables for Windows code
  47. #if TARGET_OS_WIN32
  48. #endif
  49.  
  50. long                        gMaxMilliSecToUse = 0L;    
  51.     
  52. // external variables
  53. extern QTParameterDialog    gEffectsDialog;
  54. extern DialogPtr            gCustomDialog;
  55. extern StateInformation        gCurrentState;
  56. extern Boolean                gUseStandardDialog;
  57. extern Boolean                gFastEffectDisplay;
  58. extern int                    gNumberOfSteps;
  59. extern unsigned short        gLoopingState;
  60. extern unsigned short        gCurrentDir;
  61. extern WindowPtr            gMainWindow;
  62. extern GWorldPtr            gGW1;
  63. extern GWorldPtr            gGW2;
  64. extern GWorldPtr            gGW3;
  65.  
  66.  
  67. //////////
  68. //
  69. // InitApplication
  70. // Do any application-specific initialization.
  71. //
  72. // The theStartPhase parameter determines which "phase" of application start-up is executed,
  73. // *before* the MDI frame window is created or *after*. This distinction is relevant only on
  74. // Windows, so on MacOS, you should always use kInitAppPhase_BothPhases.
  75. //
  76. //////////
  77.  
  78. void InitApplication (UInt32 theStartPhase)
  79. {
  80.     // ***do any start-up activities that should occur before the MDI frame window is created
  81.     if (theStartPhase & kInitAppPhase_BeforeCreateFrameWindow) {
  82.         // check to make sure that QuickTime video effects are available;
  83.         // we depend on these features  
  84.         if (!QTUtils_HasQuickTimeVideoEffects())
  85.             QuitFramework();
  86.     }
  87.  
  88.     // ***do any start-up activities that should occur after the MDI frame window is created
  89.     if (theStartPhase & kInitAppPhase_AfterCreateFrameWindow) {
  90.         // initialize for QuickTime effects
  91.         QTEffects_Init();
  92.     }
  93. }
  94.  
  95.  
  96. //////////
  97. //
  98. // StopApplication
  99. // Do any application-specific shut-down.
  100. //
  101. // The theStopPhase parameter determines which "phase" of application shut-down is executed,
  102. // *before* any open movie windows are destroyed or *after*.
  103. //
  104. //////////
  105.  
  106. void StopApplication (UInt32 theStopPhase)
  107. {
  108.     if (theStopPhase & kStopAppPhase_BeforeDestroyWindows)
  109.         QTEffects_Stop();
  110. }
  111.  
  112.  
  113. //////////
  114. //
  115. // DoIdle
  116. // Do any processing that can/should occur at idle time.
  117. //
  118. //////////
  119.  
  120. void DoIdle (WindowReference theWindow)
  121. {
  122.     WindowObject         myWindowObject = NULL;
  123.     GrafPtr             mySavedPort;
  124.     
  125.     GetPort(&mySavedPort);
  126.     MacSetPort(GetPortFromWindowReference(theWindow));
  127.     
  128.     myWindowObject = GetWindowObjectFromWindow(theWindow);
  129.     if (myWindowObject != NULL) {
  130.         MovieController        myMC = NULL;
  131.     
  132.         myMC = (**myWindowObject).fController;
  133.         if (myMC != NULL) {
  134.  
  135. #if TARGET_OS_MAC
  136.             // restore the cursor to the arrow
  137.             // if it's outside the front movie window or outside the window's visible region
  138.             if (theWindow == GetFrontMovieWindow()) {
  139.                 Rect    myRect;
  140.                 Point    myPoint;
  141.                 
  142.                 GetMouse(&myPoint);
  143.                 MCGetControllerBoundsRect(myMC, &myRect);
  144.                 if (!MacPtInRect(myPoint, &myRect) || !PtInRgn(myPoint, GetPortFromWindowReference(theWindow)->visRgn))
  145.                     MacSetCursor(&qd.arrow);
  146.             }
  147. #endif    // TARGET_OS_MAC
  148.         }
  149.     }
  150.     
  151.     MacSetPort(mySavedPort);
  152. }
  153.  
  154.  
  155. //////////
  156. //
  157. // DoUpdateWindow
  158. // Update the specified window.
  159. //
  160. //////////
  161.  
  162. void DoUpdateWindow (WindowReference theWindow, Rect *theRefreshArea)
  163. {
  164. #pragma unused(theRefreshArea)
  165.  
  166.     GrafPtr             mySavedPort;
  167.     WindowPtr            myWindow = GetPortFromWindowReference(theWindow);
  168.     
  169.     GetPort(&mySavedPort);
  170.     MacSetPort((GrafPtr)myWindow);
  171.     // update the main effects window only if we are not showing an effect;
  172.     // otherwise, we will get a flash of the first source image if there is
  173.     // an update while the effect is running
  174.     
  175.     // because the effect updates consecutive frames relatively quickly
  176.     // while it is running, the effect drawing acts as an update scheme anyway
  177.     if (!gCurrentState.fShowingEffect) {
  178.         BeginUpdate(GetPortFromWindowReference(theWindow));
  179.         if (myWindow == gMainWindow)
  180.             // draw the main effects window
  181.             QTEffects_DrawEffectsWindow();
  182.         else    
  183.             // draw the movie controller and its movie
  184.             MCDoAction(GetMCFromWindow(theWindow), mcActionDraw, myWindow);
  185.     
  186.         EndUpdate(GetPortFromWindowReference(theWindow));
  187.     }
  188.     
  189.     MacSetPort(mySavedPort);
  190. }
  191.  
  192.  
  193. //////////
  194. //
  195. // HandleContentClick
  196. // Handle mouse button clicks in the specified window.
  197. //
  198. //////////
  199.  
  200. void HandleContentClick (WindowReference theWindow, EventRecord *theEvent)
  201. {
  202. #pragma unused(theEvent)
  203.     WindowPtr            myWindow = GetPortFromWindowReference(theWindow);
  204.  
  205.     // clicking in the main effects window stops the effect
  206.     if (myWindow == gMainWindow) {
  207.         gCurrentState.fShowingEffect = false;
  208.         gCurrentState.fTime = 1;
  209.         QTEffects_DrawEffectsWindow();
  210.     }
  211. }
  212.  
  213.  
  214. //////////
  215. //
  216. // HandleApplicationKeyPress
  217. // Handle application-specific key presses.
  218. // Returns true if the key press was handled, false otherwise.
  219. //
  220. //////////
  221.  
  222. Boolean HandleApplicationKeyPress (char theCharCode)
  223. {
  224.     Boolean        isHandled = true;
  225.     
  226.     switch (theCharCode) {
  227.     
  228.         // @@@HANDLE APPLICATION-SPECIFIC KEY PRESSES HERE
  229.  
  230.         default:
  231.             isHandled = false;
  232.             break;
  233.     }
  234.  
  235.     return(isHandled);
  236. }
  237.  
  238.  
  239. #if TARGET_OS_MAC
  240. //////////
  241. //
  242. // CreateMovieWindow
  243. // Create a window to display a movie in.
  244. //
  245. //////////
  246.  
  247. WindowRef CreateMovieWindow (Rect *theRect, Str255 theTitle)
  248. {
  249.     WindowRef            myWindow;
  250.         
  251.     myWindow = NewCWindow(NULL, theRect, theTitle, false, noGrowDocProc, (WindowPtr)-1L, true, 0);
  252.     return(myWindow);
  253. }
  254. #endif
  255.  
  256.  
  257. //////////
  258. //
  259. // HandleApplicationMenu
  260. // Handle selections in the application's menus.
  261. //
  262. // The theMenuItem parameter is a UInt16 version of the Windows "menu item identifier". 
  263. // When called from Windows, theMenuItem is simply the menu item identifier passed to the window proc.
  264. // When called from MacOS, theMenuItem is constructed like this:
  265. //     *high-order 8 bits == the Macintosh menu ID (1 thru 256)
  266. //     *low-order 8 bits == the Macintosh menu item (sequential from 1 to ordinal of last menu item in menu)
  267. // In this way, we can simplify the menu-handling code. There are, however, some limitations,
  268. // mainly that the menu item identifiers on Windows must be derived from the Mac values. 
  269. //
  270. //////////
  271.  
  272. void HandleApplicationMenu (UInt16 theMenuItem)
  273. {
  274.     OSErr                myErr = noErr;
  275.     
  276.     switch (theMenuItem) {
  277.         case IDM_SELECT_EFFECT:                    // let the user select an effect
  278.         
  279.             // stop the current effect (if any) from playing
  280.             gCurrentState.fShowingEffect = false;
  281.             gCurrentState.fTime = 0;
  282.             QTEffects_DrawEffectsWindow();
  283.             
  284.             // let the user select an effect
  285.             myErr = QTEffects_LetUserChooseEffect();
  286.             if (myErr != noErr)
  287.                 break;
  288.  
  289.             // if the sample description is already allocated, deallocate it
  290.             if (gCurrentState.fSampleDescription != NULL)
  291.                 DisposeHandle((Handle)gCurrentState.fSampleDescription);
  292.                 
  293.             // create a sample description for the effect
  294.             gCurrentState.fSampleDescription = QTEffects_MakeSampleDescription(gCurrentState.fEffectType, kWidth, kHeight);
  295.             if (gCurrentState.fSampleDescription == NULL)
  296.                 break;
  297.             
  298.             // if the effect description is already allocated, dispose of it
  299.             if (gCurrentState.fEffectDescription != NULL)
  300.                 QTDisposeAtomContainer(gCurrentState.fEffectDescription);
  301.             
  302.             // set up a new effect description
  303.             gCurrentState.fEffectDescription = QTEffects_CreateEffectDescription(gCurrentState.fEffectType, kSourceOneName, kSourceTwoName);
  304.             if (gCurrentState.fEffectDescription == NULL)
  305.                 break;
  306.                 
  307.             // prompt the user to select options
  308.             myErr = QTEffects_LetUserCustomizeEffect(gCurrentState.fEffectDescription);
  309.  
  310.             break;
  311.  
  312.         case IDM_RUN_EFFECT:
  313.             gCurrentState.fShowingEffect = true;
  314.             gCurrentState.fSteppingEffect = false;
  315.             break;
  316.  
  317.         case IDM_STEP_AHEAD:
  318.             gCurrentState.fShowingEffect = true;
  319.             gCurrentState.fSteppingEffect = true;
  320.             gCurrentDir = kForward;
  321.             gFastEffectDisplay = false;
  322.             break;
  323.  
  324.         case IDM_STEP_BACK:
  325.             gCurrentState.fShowingEffect = true;
  326.             gCurrentState.fSteppingEffect = true;
  327.             gCurrentDir = kBackward;
  328.             gFastEffectDisplay = false;
  329.             break;
  330.  
  331.         case IDM_MAKE_EFFECT_MOVIE:
  332.             QTEffects_CreateEffectsMovie(gCurrentState.fEffectType, gCurrentState.fEffectDescription, kWidth, kHeight);
  333.             break;
  334.  
  335.         case IDM_GET_FIRST_PICTURE:
  336.             myErr = QTEffects_GetPictureAsGWorld(kWidth, kHeight, kDepth, &gGW1);
  337.             if (myErr == noErr) {
  338.             
  339.                 // we need to refresh image descriptions, etc.
  340.                 LockPixels(GetGWorldPixMap(gGW1));
  341.                 QTEffects_SetUpEffectSequence();
  342.                 QTEffects_DrawEffectsWindow();
  343.             }
  344.             break;
  345.             
  346.         case IDM_GET_SECOND_PICTURE:
  347.             myErr = QTEffects_GetPictureAsGWorld(kWidth, kHeight, kDepth, &gGW2);
  348.             if (myErr == noErr) {
  349.                 // we need to refresh image descriptions, etc.
  350.                 LockPixels(GetGWorldPixMap(gGW2));
  351.                 QTEffects_SetUpEffectSequence();
  352.                 QTEffects_DrawEffectsWindow();
  353.             }
  354.             break;
  355.             
  356.         case IDM_NO_LOOPING:
  357.         case IDM_NORMAL_LOOPING:
  358.         case IDM_PALINDROME_LOOPING:
  359.             gLoopingState = theMenuItem;
  360.             gFastEffectDisplay = (theMenuItem == IDM_NO_LOOPING);
  361.             break;
  362.             
  363.         case IDM_STANDARD_DIALOG:
  364.         case IDM_CUSTOM_DIALOG:
  365.             gUseStandardDialog = (theMenuItem == IDM_STANDARD_DIALOG);
  366.             break;
  367.             
  368.         case IDM_FAST_DISPLAY:
  369.             gFastEffectDisplay = !gFastEffectDisplay;
  370.             gLoopingState = kNoLooping;
  371.             break;
  372.  
  373.         default:
  374.             break;
  375.     } // switch (theMenuItem)
  376. }
  377.  
  378.  
  379. //////////
  380. //
  381. // AdjustApplicationMenus
  382. // Adjust state of items in the application's menus.
  383. //
  384. //////////
  385.  
  386. void AdjustApplicationMenus (WindowReference theWindow, MenuReference theMenu)
  387. {
  388. #pragma unused(theWindow)
  389.     MenuReference            myMenu;
  390.     
  391. #if TARGET_OS_WIN32
  392.     myMenu = theMenu;
  393. #endif
  394.  
  395.     // adjust the Settings menu
  396. #if TARGET_OS_MAC
  397. #pragma unused(theMenu)
  398.     myMenu = GetMenuHandle(kSettingsMenu);
  399. #endif
  400.  
  401.     SetMenuItemCheck(myMenu, IDM_NO_LOOPING, (gLoopingState == kNoLooping));
  402.     SetMenuItemCheck(myMenu, IDM_NORMAL_LOOPING, (gLoopingState == kNormalLooping));
  403.     SetMenuItemCheck(myMenu, IDM_PALINDROME_LOOPING, (gLoopingState == kPalindromeLooping));
  404.     SetMenuItemCheck(myMenu, IDM_STANDARD_DIALOG, (gUseStandardDialog == true));
  405.     SetMenuItemCheck(myMenu, IDM_CUSTOM_DIALOG, (gUseStandardDialog == false));
  406.     SetMenuItemCheck(myMenu, IDM_FAST_DISPLAY, (gFastEffectDisplay == true));
  407.  
  408.     // now, do all Effects menu adjustment
  409. #if TARGET_OS_MAC
  410.     myMenu = GetMenuHandle(kEffectMenu);
  411. #endif
  412.  
  413. #if TARGET_OS_MAC
  414.     // we don't allow creating new files here...
  415.     SetMenuItemState(GetMenuHandle(mFile), iNew, kDisableMenuItem);
  416. #endif
  417. }
  418.  
  419.  
  420. //////////
  421. //
  422. // DoApplicationEventLoopAction
  423. // Perform any application-specific event loop actions.
  424. //
  425. // Return true to indicate that we've completely handled the event here, false otherwise.
  426. //
  427. //////////
  428.  
  429. Boolean DoApplicationEventLoopAction (EventRecord *theEvent)
  430. {
  431.     Boolean        isHandled = false;
  432.     
  433.     // run the next step(s) of the effect
  434.     QTEffects_ProcessEffect();
  435.     
  436.     // see if the event is meant for the effects parameter dialog box
  437.     if (gEffectsDialog != 0L)
  438.         isHandled = QTEffects_HandleEffectsDialogEvents(theEvent, 0);
  439.  
  440. #if TARGET_OS_MAC
  441.     // handle events for any application-specific windows
  442.     if (!isHandled)
  443.         isHandled = QTEffects_HandleEffectsWindowEvents(theEvent);
  444. #endif
  445.  
  446.     return(isHandled);
  447. }
  448.  
  449.  
  450. //////////
  451. //
  452. // AddControllerFunctionality
  453. // Configure the movie controller.
  454. //
  455. //////////
  456.  
  457. void AddControllerFunctionality (MovieController theMC)
  458. {
  459.     long            myControllerFlags;
  460.     
  461.     // CLUT table use    
  462.     MCDoAction(theMC, mcActionGetFlags, &myControllerFlags);
  463.     MCDoAction(theMC, mcActionSetFlags, (void *)(myControllerFlags | mcFlagsUseWindowPalette));
  464.  
  465.     // enable keyboard event handling    
  466.     MCDoAction(theMC, mcActionSetKeysEnabled, (void *)true);
  467.     
  468.     // disable drag support
  469.     MCDoAction(theMC, mcActionSetDragEnabled, (void *)false);
  470. }
  471.  
  472.  
  473. //////////
  474. //
  475. // InitApplicationWindowObject
  476. // Do any application-specific initialization of the window object.
  477. //
  478. //////////
  479.  
  480. void InitApplicationWindowObject (WindowObject theWindowObject)
  481. {
  482. #pragma unused(theWindowObject)
  483. }
  484.  
  485.  
  486. //////////
  487. //
  488. // RemoveApplicationWindowObject
  489. // Do any application-specific clean-up of the window object.
  490. //
  491. //////////
  492.  
  493. void RemoveApplicationWindowObject (WindowObject theWindowObject)
  494. {
  495. #pragma unused(theWindowObject)
  496.     // DoDestroyMovieWindow in MacFramework.c or MovieWndProc in WinFramework.c
  497.     // releases the window object itself
  498. }
  499.  
  500.  
  501. //////////
  502. //
  503. // ApplicationMCActionFilterProc 
  504. // Intercept some mc actions for the movie controller.
  505. //
  506. // NOTE: The theRefCon parameter is a handle to a window object record.
  507. //
  508. //////////
  509.  
  510. PASCAL_RTN Boolean ApplicationMCActionFilterProc (MovieController theMC, short theAction, void *theParams, long theRefCon)
  511. {
  512. #pragma unused(theMC, theParams)
  513.  
  514.     Boolean                isHandled = false;
  515.     WindowObject        myWindowObject = NULL;
  516.     
  517.     myWindowObject = (WindowObject)theRefCon;
  518.     if (myWindowObject == NULL)
  519.         return(isHandled);
  520.         
  521.     switch (theAction) {
  522.     
  523.         // handle window resizing
  524.         case mcActionControllerSizeChanged:
  525.             SizeWindowToMovie(myWindowObject);
  526.             break;
  527.  
  528.         default:
  529.             break;
  530.             
  531.     }    // switch (theAction)
  532.     
  533.     return(isHandled);    
  534. }
  535.  
  536.  
  537.